package com.lollipop.rabbitmqspringboot.config;

import lombok.extern.slf4j.Slf4j;
import org.springframework.amqp.core.ReturnedMessage;
import org.springframework.amqp.rabbit.connection.CorrelationData;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.stereotype.Component;

import javax.annotation.PostConstruct;
import javax.annotation.Resource;

/**
 * @Author: Lollipop
 * @Date: 2021-10-20 19:48
 * @Description: 发布确认模式-回调
 */
@Slf4j
@Component
public class MyCallBack implements RabbitTemplate.ConfirmCallback, RabbitTemplate.ReturnsCallback {

    @Resource
    private RabbitTemplate rabbitTemplate;

    /**
     * 将当前类注入到ConfirmCallback中
     */
    @PostConstruct
    public void init() {
        rabbitTemplate.setConfirmCallback(this);
        rabbitTemplate.setReturnsCallback(this);
    }

    /**
     * 交换机确认回调方法
     * 情况1：发消息，交换机接收到了-回调
     * CorrelationData保存回调消息的ID和相关信息 ack=true cause=null
     * 情况2：发消息，交换机接收失败-回调
     * CorrelationData保存回调消息的ID和相关信息 ack=false cause=失败原因
     *
     * @param correlationData
     * @param ack
     * @param cause
     */
    @Override
    public void confirm(CorrelationData correlationData, boolean ack, String cause) {
        String id = correlationData.getId() != null ? correlationData.getId() : "";
        if (ack) {
            log.info("交换机成功接收ID为：{}的消息", id);
        } else {
            log.info("交换机没有接收到ID为：{}的消息", id, "原因是：{}", cause);
        }
    }

    /**
     * 消息发送不到目的地，回退消息给生产者
     *
     * @param returnedMessage
     */
    @Override
    public void returnedMessage(ReturnedMessage returnedMessage) {
        log.info("消息{}被交换机{}退回，原因是：{}，路由key：{}", returnedMessage.getMessage(), returnedMessage.getExchange(), returnedMessage.getReplyText(), returnedMessage.getRoutingKey());
    }
}
